//package minijava;
//import java.util.List;
//import java_cup.runtime.ComplexSymbolFactory.Location;
public abstract class Stmt {
    public class Loop : Stmt {
        public Stmt body;
        public Cond cond;
        public Loop(Cond c, Stmt t) {
            cond = c;
            body = t;
        }
        public String ToString() {
            return "while (" + cond + ")" + body + "\n";
        }
        public override void accept(MinijavaVisitor v) {
            if (!v.preVisit(this)) return;
            cond.accept(v);
            body.accept(v);
            v.postVisit(this);
        }
    }
    public static Stmt whileloop(Cond c, Stmt s) {
        return new Loop(c, s);
    }
    public class IfThenElse : Stmt {
        public Stmt then;
        public Stmt els;
        public Cond cond;
        public IfThenElse(Cond c, Stmt t, Stmt e) {
            cond = c;
            then = t;
            els = e;
        }
        public String ToString() {
            return "if(" + cond + ")" + then + ((els == null) ? "" : ("else " + els)) + "\n";
        }
        public override void accept(MinijavaVisitor v) {
            if (!v.preVisit(this)) return;
            cond.accept(v);
            then.accept(v);
            if (els != null) els.accept(v);
            v.postVisit(this);
        }
    }
    public static Stmt ifthenelse(Cond c, Stmt t, Stmt e) {
        return new IfThenElse(c, t, e);
    }
    public static Stmt ifthen(Cond c, Stmt t) {
        return new IfThenElse(c, t, null);
    }
    public class Write : Stmt {
        public Expr e;
        public String s;
        public Write(Expr e) {
            this.e = e;
        }
        public Write(String s) {
            this.s = s;
        }
        public String ToString() {
            if (e == null) return "write(\"" + s + "\");\n";
            return "write(" + e + ");\n";
        }
        public override void accept(MinijavaVisitor v) {
            if (!v.preVisit(this)) return;
            if (e != null) e.accept(v);
            v.postVisit(this);
        }
    }
    public static Stmt write(Expr e) {
        return new Write(e);
    }
    public static Stmt write(String s) {
        return new Write(s);
    }
    public class Read : Stmt {
        public String lhs;
        public String message;
        public Location left, right;
        public Read(Location l, String s, Location r) {
            lhs = s;
            left = l;
            right = r;
        }
        public Read(Location l, String ident, String mess, Location r) {
            lhs = ident;
            message = mess;
            left = l;
            right = r;
        }
        public String ToString() {
            if (message == null) return lhs + "=read();\n";
            return lhs + "=read();\n";
        }
        public override void accept(MinijavaVisitor v) {
            v.visit(this);
        }
    }
    public static Stmt read(Location l, String s, Location r) {
        return new Read(l, s, r);
    }
    public static Stmt read(Location l, String ident, String s, Location r) {
        return new Read(l, ident, s, r);
    }
    public class Assign : Stmt {
        public String lhs;
        public Expr rhs;
        public Location left, right;
        public Assign(Location l, String s, Expr e, Location r) {
            lhs = s;
            rhs = e;
            left = l;
            right = r;
        }
        public String ToString() {
            return lhs + "=" + rhs + ";\n";
        }
        public override void accept(MinijavaVisitor v) {
            v.preVisit(this);
            rhs.accept(v);
            v.postVisit(this);
        }
    }
    public static Stmt assign(Location l, String i, Expr e, Location r) {
        return new Assign(l, i, e, r);
    }
    public class Compound : Stmt {
        public List<Stmt> ls;
        public Compound(List<Stmt> l) {
            ls = l;
        }
        public String ToString() {
            String ret = "{\n";
            foreach (Stmt s in ls) ret += s;
            return ret + "}";
        }
        public override void accept(MinijavaVisitor v) {
            if (!v.preVisit(this)) return;
            foreach (Stmt s in ls) s.accept(v);
            v.postVisit(this);
        }
    }
    public static Stmt compound(List<Stmt> l) {
        return new Compound(l);
    }
    public class Empty : Stmt {
        public Empty() {
        }
        public override void accept(MinijavaVisitor v) {
            v.visit(this);
        }
    }
    public static Stmt empty() {
        return new Empty();
    }
    public abstract void accept(MinijavaVisitor v);

}
